This invention generally relates to the field of application program development, and more particularly to providing automatic support for state-reversion transactions.
Providing support for state-reversion operations in an application program is traditionally a complex and error-prone task. For highly complex application programs, such as Computer Aided Design (CAD) projects, the task is particularly difficult. One reason for this difficulty is that CAD designs are frequently revised before a design is deemed completed. For example, designs frequently evolve and change according to revised design goals or when certain features do not yield desired results. Thus, in any particular design session, a designer may make many substantial changes to a design, where each change may then require changes to other components of the design. Consequently, implementation of a robust state-reversion system becomes correspondingly complex.
For brevity, the term xe2x80x9cundoxe2x80x9d, unless indicated otherwise by wording or context, generally refers to state-reversion operations, as well as related undo, redo, abort, and operations. The term state-reversion means reverting a model to an earlier state, like an undo, but where a new current state is created corresponding to the earlier state. Undo is used to generally represent all of these operations, since they can be viewed as particular implementations or variations of disclosed mechanisms for reversing changes made within an application program. The term xe2x80x9creversionxe2x80x9d refers to program code implementing such state-reversion, undo, redo, and abort support.
Part of the reason for the difficulty in providing undo support in a solid modeling system, and hence difficulty in providing for state-reversion, is that there are no inverse operations for most Boolean operations applied to objects within a model. Thus, one must capture the details of what has changed at a very low level, e.g., at the data structure level. In addition, many user operations are often ill formed, causing the operation to fail after partial calculation of the user request, and leaving the model in an unstable state that requires correction.
Historically, there have been several methods of incorporating undo support within the source code of an application program. The simplest (and most limiting) has been to save to permanent storage a check-point version of a design in progress. This saved copy can be re-loaded if the design goes awry. There are significant problems with this approach, however. First, restorations are limited to the design as saved. Second, designs can be extremely complex, and significant resources (e.g., processor, memory, storage, etc.) and time can be required to save and re-load designs; this limits the frequency of such backups.
An improved method has been to utilize an object-based history mechanism. That is, design environments typically break a drawing into multiple objects, frequently arranged as a graph. Drawing objects can be made responsible for saving current state information before effecting a change to its state. The saved state information can be used to revert an object to a previous state. However, this approach also suffers several significant shortcomings. One shortcoming is that every object must properly handle reversions (e.g., have appropriate program code to perform an undo). Similar to a chain being only as strong as the weakest link, an entire undo mechanism can be compromised by one object""s failure to properly restore its state. Another is that every object must consume Central Processing Unit (CPU) resources to effect the state saving, and may seriously degrade program performance.
Another method has been to maintain a list of inverse operations. If a user rotates an object by ninety degrees, an inverse operation is recorded to undo the rotation. But, this method has shortcomings. One is that performing an inverse operation is generally at least as resource consuming as the original calculation to get to the current state. Another, more problematic shortcoming, is that some operations have no inverse. For example, application of a lossy filter discards original data that cannot be recovered.
Yet another method has been to maintain a history of design actions, where a reversion is effected by re-computing the entire design up to some previous state. This solution is similar to applying inverse operations, and overcomes the problem with lossy operations. However, operations relying on real-time, transient, or random data still cannot be reversed. And, since a design may have a very large number of operations to recreate, this solution can also be extremely slow and resource intensive.
But, each of the above methods places a burden on an application program designer (e.g., the CAD/CAM developer) to design and implement a complex reversion feature. Due to such complexity, a significant portion of application program design time can be expended in order to properly implement it and allow its use throughout the application program. Also, there is no guarantee that it will be implemented correctly. And, since such a feature is integral to an application program, it is unlikely that resulting program code will be easily portable to a different application program.
Programs and programming environments can be modified to provide automatic support for reverting program memory states, allowing automatic support for state-reversion, undo, redo, and abort operations. Memory allocation code (e.g., functions, procedures, etc.) can be modified to mark allocated memory as protected, and assign an exception handler to such memory. For example, an exception filter can be associated with a memory region, where the filter decides, based on the exception details, whether the exception represents an attempt to modify memory which has been protected. Modifications are caught, providing opportunity to preserve memory before its modification. This allows retrieving previous program states. State-reversion of a model stored in a memory can be achieved by tracking changes to the memory by application of transactions to current states of the model. When a first transaction is received, the model has a first state. Application of the transaction results in a second state. Changes to the memory storing model are tracked between the first and second states. Thus, on receiving a state-reversion request to revert back to the first state, a new current model state can be created, where this current state is equivalent to the first state.